package com.ctrip.corp.obt.shard.loader;


import com.ctrip.corp.obt.generic.utils.ExceptionUtils;
import com.ctrip.corp.obt.shard.constants.SourceLoadMode;
import com.ctrip.corp.obt.shard.holder.ShardSourceHolder;
import com.ctrip.corp.obt.shard.manager.DataShardSourceManager;
import lombok.extern.slf4j.Slf4j;

import java.util.Set;

/**
 * @author marco.zheng
 * @version 1.0
 * @date 2022/01/14
 * @desc 全量数据分片加载器
 * @see
 * @since 1.0
 */
@Slf4j
public class FullShardSourceLoader extends AbstractShardSourceLoader {


    public FullShardSourceLoader(DataShardSourceManager dataShardSourceManager) {
        super(dataShardSourceManager);
    }

    /**
     * Startup加载
     *
     * @return
     */
    @Override
    public void loadOnStartup() {
        DataShardSourceManager dataShardSourceManager = getDataShardSourceManager();
        Set<String> finishLoadSources = dataShardSourceManager.cacheShardSource(null);
        dataShardSourceManager.initDataSource();
        log.info("Startup loading shard source, source load mode:[{}], source num:{}", SourceLoadMode.FULL, finishLoadSources.size());
    }

    @Override
    public void refresh(String tenantId) {
        // 重新加载数据源
        // loadOnStartup();
        reloadDataSource(tenantId);
    }

    /**
     * 指定分组加载(后期客户量大，每个pod只能按照策略加载有限的ds)
     * 可通过control plane进行分配
     *
     * @return
     */
    @Override
    public Set<String> loadBySources(Set<String> tenantIds) {
        throw ExceptionUtils.mpe("Full sourceLoadMode do not allow load by source, per all sources has bean loaded");
    }

    /**
     * 重新加载数据源
     * 应对场景：
     *  1.监听已创建数据源的插件修改操作
     *  2.监听新创建数据源
     *  （对于删除，没有监听相关的操作）
     * 
     * @param tenantId
     */
    private void reloadDataSource(String tenantId) {

        if (ShardSourceHolder.contains(tenantId)) {
            // 获取datasource的操作类
            DataShardSourceManager dataShardSourceManager = getDataShardSourceManager();
            // 只刷新数据源插件
            dataShardSourceManager.refreshSourcePlugins(tenantId);
        } else {
            loadOnStartup();
        }
        log.info("Refresh shard source, source load mode:[{}], source from:{}", SourceLoadMode.FULL, tenantId);
    }

}
